package Groep1;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Scanner;

import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.EditorKit;
import javax.swing.text.ElementIterator;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;

public class Toepasingstaak_2_1 {
	
	//Wat variablen
	static ArrayList<String> downloads = new ArrayList<String>();
	static URL mainURL;
	
	/**
	 * Download method, voor het downloaden van een URL naar een bestand. 
	 * 
	 * @param url
	 * @param localFileName
	 */
	public static void download(URL url, String localFileName) {
		//Wat streams/connection variabelen
		OutputStream out = null;
		URLConnection conn = null;
		InputStream  in = null;
		
		try {			
			//Opslaan stream aanmaken
			out = new BufferedOutputStream(new FileOutputStream(localFileName));
			
			//Connectie met URL maken
			conn = url.openConnection();
			
			//Inkomende data ophalen
			in = conn.getInputStream();
			
			byte[] buffer = new byte[1024];
			int numRead;
			long numWritten = 0;
			
			//Door data lopen
			while ((numRead = in.read(buffer)) != -1) {
				//Naar file schrijven
				out.write(buffer, 0, numRead);
				//Bijhouden wat al gedaan is
				numWritten += numRead;
			}	
		//Error afhandeling
		} 
		catch (Exception exception) {
			//exception.printStackTrace();
		}
		//Uiteindelijk sluiten van streams
		finally {
			try {
				//Streams sluiten/opslaan
				if (in != null) {
					in.close();
				}
				if (out != null) {
					out.close();
				}
			} catch (IOException ioe) {
			}
		}
	}
	
	/**
	 * getLinks method, zoekt naar links in een URL
	 * 
	 * @param uriStr
	 * @return ArrayList<String>
	 */
    public static ArrayList<String> getLinks(URL uriStr) {
    	//Lege ArrayList aanmaken
    	ArrayList<String> result = new ArrayList<String>();
    	
        try {
            //HTML reader voor de URL aanmaken
            URLConnection connection = uriStr.openConnection();
            Reader rd = new InputStreamReader(connection.getInputStream());
        	
            //HTML code parsen
            EditorKit kit = new HTMLEditorKit();
            HTMLDocument doc = (HTMLDocument)kit.createDefaultDocument();
            doc.putProperty("IgnoreCharsetDirective", new Boolean(true));
            kit.read(rd, doc, 0);
            
            //Iterator aanmaken voor de TAGS
            ElementIterator it = new ElementIterator(doc);
            javax.swing.text.Element elem = null;
             
            //Door alle TAGS in de HTML file lopen
            while ((elem = it.next()) != null) {
           	
            	//A TAG eruitvissen
            	AttributeSet s = (AttributeSet)elem.getAttributes().getAttribute(HTML.Tag.A);

            	//A TAG is gevult, dan HREF atribuut in de result plaatsen
            	if (s != null) {
            	  String href = (String)s.getAttribute(HTML.Attribute.HREF);
            	  result.add(href); 
            	}

            }
            
        //Wat error afhandelingen
        } catch (MalformedURLException e) {
        	 System.out.println("MalformedURLException");
        } catch (BadLocationException e) {
        	 System.out.println("BadLocationException ");
        } catch (IOException e) {
        	System.out.println("Could not download: "+uriStr.toString());
        }
  
        //Alle gevonden links teruggeven       
        return result;
    }

    /**
     * Method loopLinks, gaat alle links van een pagina downloaden
     * 
     * @param url
     * @param dir
     * @param count
     */
    public static void loopLinks(URL url, File dir, int count){
    	try {
    		//Links op pagina ophalen
    		ArrayList<String> links = getLinks(url);
    		
    		//Door gevonden urls lopen
			for (String s : links) {
						
				//URL valideren
				URL tURL = null;
				if(s.contains(mainURL.toString()) || s.contains("http"))
					tURL = new URL(s);
				else
					tURL = new URL(mainURL.toString() + s);
				
				//URL omzetten naar file
				File file = new File(tURL.getFile());
				
				//Filenaam bepalen
				String nfilename;				
				if(file.getName().contains(".html") || file.getName().contains(".htm"))
					nfilename = file.getName();
				else
					nfilename = file.getName() + ".html";
				
				//Controle of URL niet al X gedownload is
				File checkFile = new File(dir + "\\" + nfilename);
				if(!checkFile.exists() && !nfilename.contains("?")) {
					System.out.println("Download: " + tURL.toString());
					download(tURL, dir + "\\" + nfilename);
				}
			}
			
			//Ga verder met de URL
			startGetting(url, dir, count);
    	}
    	catch(Exception ex){
    		System.out.println("loopLinks");
    		ex.printStackTrace();
    		return;
    	}
    }
    
    /**
     * Method startGetting, haalt alle links * diep op
     * 
     * @param url
     * @param dir
     * @param count
     */
    public static void startGetting(URL url, File dir, int count){
    	try {
    	
    		//Links zoeken in URL
	    	ArrayList<String> links = getLinks(url);
	    	
	    	//Als diepte groter is dan 0 in de URL nieuwe links zoeken
	    	if(count > 0){
				
	    		//Diepte verlagen met 1
				count = count -1;
				
				//Door gevonden links loopen
				for (String s : links) {
					
					//URL valideren
					URL tURL = null;
					if(s.contains(mainURL.toString()) || s.contains("http"))
						tURL = new URL(s);
					else
						tURL = new URL(mainURL.toString() + s);
					
					//Links downloaden van site
					loopLinks(tURL, dir, count);
				}
		}
    	}catch(Exception ex) {
    		System.out.println("startGetting");
    		ex.printStackTrace();
    	}
    }
    
    /**
     * Method main
     * 
     * @param args
     */
	public static void main(String[] args) {		
		
		try {
			//URL opvragen van user
			Scanner scan = new Scanner(System.in);		
			System.out.println("Type location to download:");
			String input = scan.nextLine();
			scan.close();
			
			//URL valideren
			if(input.contains("http://") || input.contains("https://"))
				mainURL = new URL(input);
			else
				mainURL = new URL("http://" + input);
			
			//Download map voor site aanmaken
			File dir = new File(mainURL.getHost());
			dir.mkdir();
			
			//Filename toekennen aan te downloaden file
			String filename = mainURL.getFile();			
			if(filename.equals(""))
				filename = "index.html";
					
			//Hoofdpagina downloaden/opslaan
			download(mainURL, dir + "\\" + filename);
			
			//Links in URL zoeken en downloaden (3 diep)
			startGetting(mainURL, dir, 3);
						
		} catch (Exception ex) {
			System.out.println("main");
			ex.printStackTrace();
		}
	}

}
